'use strict';

const AlipaySdk = require('alipay-sdk').default;
const AlipayFormData = require('alipay-sdk/lib/form').default;

let alipaySdkInstance; // 支付SDK实例
let payConfig; // 支付配置

// 读取支付配置
think.extModel('pay', 'pay').where({
    type: 'alipay',
    status: 1,
}).find()
    .then(res => {
        payConfig = JSON.parse(res.setting); // 解析支付配置
    })
    .catch(e => think.logger.error(e));

module.exports = class extends think.Service {
    constructor(config) {
        super();
        this.config = config = Object.assign({}, config, payConfig);

        // 判断实例
        if (!(alipaySdkInstance instanceof AlipaySdk) || config) {
            alipaySdkInstance = new AlipaySdk({
                appId: config.appId, // 开放平台上创建应用时生成的 appId
                privateKey: config.privateKey, // 应用私钥字符串
                signType: config.signType, // 签名算法
                alipayPublicKey: config.alipayPublicKey, // 支付宝公钥，需要对结果验签时候必填
                gateway: config.gateway, // 支付宝网关地址
                timeout: config.timeout, // 网关超时时间，单位毫秒
                camelcase: config.camelcase, // 是否把网关返回数据中的的下划线 key 转换为驼峰写法
            });
        }

        this.alipaySdk = alipaySdkInstance;
    }

    /**
     * 发送支付请求
     * @param {Object} params 订单参数
     * @param {Boolean} isMobile 是否手机端
     * @return {*} ?
     */
    async pay(params, isMobile) {
        try {
            const formData = new AlipayFormData();
            formData.addField('notifyUrl', this.config.notifyUrl); // 异步通知URL
            formData.addField('returnUrl', this.config.returnUrl); // 同步通知URL

            formData.addField('bizContent', {
                outTradeNo: params.orderNo, // 商户订单号,64个字符以内、可包含字母、数字、下划线；需保证在商户端不重复
                productCode: 'FAST_INSTANT_TRADE_PAY', // 销售产品码，与支付宝签约的产品码名称。注：目前仅支持FAST_INSTANT_TRADE_PAY
                totalAmount: params.price, // 订单总金额，单位为元，精确到小数点后两位，取值范围[0.01,100000000]
                subject: params.title, // 订单标题
            });
            const payMethod = isMobile ? 'alipay.trade.wap.pay' : 'alipay.trade.page.pay';
            const result = await this.alipaySdk.exec(payMethod,
                {},
                {
                    formData,
                });

            return result;
        } catch (e) {
            think.logger.error(e);
            return false;
        }
    }

    /**
     * 查询订单支付结果
     * @param {String} orderNo 订单号
     */
    async query(orderNo) {
        const queryResult = await this.alipaySdk.exec('alipay.trade.query',
            {
                bizContent: {
                    outTradeNo: orderNo,
                },
            });
        return queryResult;
    }

    /**
     * 验证支付结果
     * @param {Object} data alipay发送的postData
     * @return {Boolean} 验证结果
     */
    async verify(data) {
        return await this.alipaySdk.checkNotifySign(data);
    }
};
